/**
 * 
 */
package org.pandazxx.picasamanager.io;

/**
 * @author pandazxx
 * 
 */
public class TransferMonitor implements InputStreamListener {
	private long transferBeginTime = -1;
	private long readBytes = 0;
	private long totalBytes = 0;
	private int sleepTime = 0;
	private CountThread thread;

	public TransferMonitor(int sleepTime, long totalBytes) {
		this.sleepTime = sleepTime;
		this.totalBytes = totalBytes;
		thread = new CountThread();
	}

	public void readFromStream(int bytes) {
		if (transferBeginTime == -1) {
			transferBeginTime = System.currentTimeMillis();
			thread.start();
		}
		readBytes += bytes;
	}

	public synchronized long getReadBytes() {
		return readBytes;
	}

	private class CountThread extends Thread {
		private boolean enable = true;

		@Override
		public void run() {

			while (enable) {
				try {
					if (transferBeginTime != -1) {
//						System.out.print("\r" + readBytes + " sent, "
//								+ getAdvangeSpeed() + " B/s");
						System.out.printf("\r %s/%s %s/s %ds remain",
								TransferSize.formatNormal(readBytes),
								TransferSize.formatNormal(totalBytes),
								TransferSize.formatNormal(getAdvangeSpeed()),
								getRemainTime());
					}
					this.sleep(sleepTime);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		private long getAdvangeSpeed() {
			long transferedTime = System.currentTimeMillis()
					- transferBeginTime;
			long advangeSpeed = transferedTime == 0 ? 0 : readBytes
					/ transferedTime * 1000;
			return advangeSpeed;
		}

		private long getRemainTime() {
			long timeRemain = -1;
			if (getAdvangeSpeed() != 0) {
				timeRemain = (totalBytes - readBytes) / getAdvangeSpeed();
			}
			return timeRemain;
		}

	}

	public void closeStream() {
		finish();
	}

	/**
	 * 
	 */
	private void finish() {
		thread.enable = false;
		if (transferBeginTime != -1) {
			System.out.print("\r" + readBytes + " sent, "
					+ thread.getAdvangeSpeed() + " B/s\n");
		}
	}

	public void readOnEnd() {
		finish();

	}
}
